<template>
  <div id="app">
    <el-upload
      class="upload-demo"
      drag
      action="/"
      :http-request="upload"
      multiple
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      <div class="el-upload__tip" slot="tip">
        只能上传jpg/png文件，且不超过500kb
      </div>
    </el-upload>
    <el-progress :percentage="percentage"></el-progress>
    <el-button @click="test">test</el-button>
    <router-view />
  </div>
</template>
<script>
import axios from "axios";
import SparkMD5 from "spark-md5";
import { test, taskInfo, initTask, preSignUrl, merge } from "./lib/api.js";
export default {
  data() {
    return {
      // baseUrl: "http://localhost:8888",
      totalSize: 0,
      uploadedSize: 0,
      percentage: 0,
    };
  },
  methods: {
    async test() {
      let a = this.$md5();

      // let a = await test();
      console.log(a);
    },
    testUpload(option) {
      debugger;
      let file = option.file;
      let { onProgress } = option;
      onProgress({ percent: 50 });
      this.getFileMd5(file).then((md5) => {
        console.log(md5);
      });
    },
    updateProcess(increment, options) {
      increment = new Number(increment);
      const { onProgress } = options;
      let factor = 1000; // 每次增加1000 byte
      let from = 0;
      // 通过循环一点一点的增加进度
      while (from <= increment) {
        from += factor;
        this.uploadedSize += factor;
        const percent = Math.round((this.uploadedSize / this.totalSize) * 100);
        if(percent>100){
        this.percentage = 100;

        }else{
          this.percentage=percent
        }
        // onProgress({ percent: percent });
      }
    },
    getFileMd5(file) {
      return new Promise((resolve, reject) => {
        let fileReader = new FileReader();

        fileReader.onload = function (event) {
          let fileMd5 = SparkMD5.ArrayBuffer.hash(event.target.result);
          resolve(fileMd5);
        };

        fileReader.readAsArrayBuffer(file);
      });
    },

    async uploadChunk() {},
    async upload(option) {
      let file = option.file;
      this.percentage = 0;
      let fileName = file.name;
      let fileSize = file.size;
      this.totalSize = fileSize;
      let chunkSize = 1024 * 1024 * 5; // 1mb
      let chunkNum = Math.ceil(fileSize / chunkSize);
      let md5 = await this.getFileMd5(file);
      // debugger
      // 查看上传进度 1:没有此记录就创建 2.上传了部分的记录，那就将
      // 已上传的分片down 回来，然后前端进行比较，上传没上传的分片
      let { code, data, msg } = await taskInfo(md5);
      if (code === 200000) {
        let task = data;

        if (!task) {
          /// 没初始化返回null
          // 如果没有初始化任务的话 ，就初始化一个上传任务
          const initTaskData = {
            identifier: md5, // MD5
            fileName: file.name, // 文件初始名字
            totalSize: file.size, // 文件的大小
            chunkSize: 5 * 1024 * 1024, // 分块的大小
          };
          let { code, data, msg } = await initTask(initTaskData);
          if (code === 200000) {
            debugger
            for (var partNumber = 1; partNumber <= chunkNum; partNumber++) {
              // 获取预上传链接
              const obj = {
                identifier: md5,
                partNumber: partNumber,
              };
              let { code, data, msg } = await preSignUrl(obj);
              const start = new Number(chunkSize) * (partNumber - 1);
              const end = start + new Number(chunkSize);
              let blog = file.slice(start, end);
              console.log("第" + partNumber + "分片");
              console.log("开始   " + start + "   end" + end);
              console.log(data);
              await axios.request({
                url: data,
                method: "PUT",
                data: blog,
                headers: { "Content-Type": "application/octet-stream" },
              });
              console.log(partNumber + " 分片 上传成功");
              this.updateProcess(blog.size, option);
            }
            let a = await merge(md5);
            console.log("合并");
            console.log(a);
          }
        } else {
          // 说明已经上传过了
          debugger;
          const { finished, path, taskRecord } = task;
          if (finished) {
            // 全部上传
         
            this.percentage = 100;
          } else { // 部分上传 断点续传
          let exitPartList=taskRecord.exitPartList
            for (var partNumber = 1; partNumber <= chunkNum; partNumber++) {
              const exitPart = (exitPartList || []).find(
                (exitPart) => exitPart.partNumber == partNumber
              );
              if (!exitPart) {
                // 根据已经上传的分片判断，不存在的菜进行上传
                // 获取预上传链接
                const obj = {
                  identifier: md5,
                  partNumber: partNumber,
                };
                let { code, data, msg } = await preSignUrl(obj);
                const start = new Number(chunkSize) * (partNumber - 1);
                const end = start + new Number(chunkSize);
                let blog = file.slice(start, end);
                console.log("第" + partNumber + "分片");
                console.log("开始   " + start + "   end" + end);
                console.log(data);
                await axios.request({
                  url: data,
                  method: "PUT",
                  data: blog,
                  headers: { "Content-Type": "application/octet-stream" },
                });
                console.log(partNumber + " 分片 上传成功");
                this.updateProcess(blog.size, option);
              }else{  // 已经上传的分片记录下上传进度
                this.updateProcess(exitPart.size, option);

              }
            }
            let a = await merge(md5);
            console.log("合并");
            console.log(a);
            // 部分上传
          }
        }
      }
    },
  },
};
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>